/**
 * This file is part of Idegen, the application to create IDE project files.
 *
 * @copyright Copyright (c) 2011-2012, Walter Tamboer http://waltertamboer.nl
 * @file Idegen/Application/CommandLineParser.hpp
 */

#ifndef IDEGEN_APPLICATION_COMMANDLINEPARSER_HPP
#define IDEGEN_APPLICATION_COMMANDLINEPARSER_HPP

namespace Idegen
{
	/** A command line parser which can recognize flags set by the command line. */
	class CommandLineParser
	{
	public:
		/** Initializes a new instance of this class. */
		CommandLineParser();

		/** Cleans up all the resources used by this class. */
		~CommandLineParser();

		/**
		 * Parses the given command line.
		 *
		 * @param[in] argc The amount of arguments.
		 * @param[in] argv The argument values.
		 * @return Returns true when parsing succeeded; false otherwise.
		 */
		bool Parse( int argc, char* argv[] );

		/**
		 * Adds the given flag to the command line options.
		 *
		 * @param[in] name The name of the flag.
		 * @param[in] description The description of this flag.
		 * @param[in] required Whether or not the flag is required.
		 */
		void AddFlag( const std::string& name, const std::string& description, bool required );

		/**
		 * Adds the given flag to the command line options.
		 *
		 * @param[in] name The name of the flag.
		 * @param[in] shortName The short name of the flag.
		 * @param[in] description The description of this flag.
		 * @param[in] required Whether or not the flag is required.
		 */
		void AddFlag( const std::string& name, const std::string& shortName, const std::string& description, bool required );

		/**
		 * Checks if the given flag has been set.
		 *
		 * @param[in] name The name of the flag to check.
		 * @return Returns true when the flag has been set; false otherwise.
		 */
		bool HasFlag( const std::string& name ) const;

		/**
		 * Gets the value of the given flag.
		 *
		 * @param[in] name The name or the shortname of the value of the flag to retrieve.
		 * @return Returns the value of the flag or an empty value if it wasn't set.
		 */
		std::string GetFlagValue( const std::string& name ) const;

	private:
		/** A flag that can be specified on the command line. */
		struct Flag
		{
			/** Whether or not the flag is required. */
			bool Required;
			
			/** Whether or not the flag has been set. */
			bool HasValueBeenSet;
			
			/** The name of the flag i.e. "-config" */
			std::string Name;
			
			/** The short name of the flag i.e. "-c" */
			std::string ShortName;

			/** The description of the flag. */
			std::string Description;
			
			/** The value of the flag. */
			std::string Value;
		};

		/**
		 * Adds the given flag to the command line options.
		 *
		 * @param[in] flag The flag that should be added.
		 */
		void AddFlag( const Flag& flag );
		
		/**
		 * A list with flags.
		 *
		 * @typedef FlagList
		 */
		typedef std::vector< Flag > FlagList;

		/** A list with all the flags of this command line. */
		FlagList m_Flags;
	};
}

#endif

